package uid.elements;

/**
 * @author Patricia Vilain
 */
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

public abstract class AbstractState {

	protected String id;
	protected List<Transition> listOutgoingTransitions;
	protected List<Transition> listIncomingTransitions;

	// NOVOS ATRIBUTOS
	protected List<Structure> listStructures;
	protected List<DataItem> listDataItems;
	protected List<InputORDataEntry> listInputORDataEntries;
	protected List<InputXORDataEntry> listInputXORDataEntries;
	protected List<InputEnumeratedData> listInputEnumeratedData;
	protected List<Text> listTexts;
	protected List<Substate> listSubstates;

	public AbstractState(String id) {
		this.id = id;
		this.listStructures = new ArrayList<Structure>();
		this.listDataItems = new ArrayList<DataItem>();
		this.listOutgoingTransitions = new ArrayList<Transition>();
		this.listIncomingTransitions = new ArrayList<Transition>();
		this.listInputORDataEntries = new ArrayList<InputORDataEntry>();
		this.listInputXORDataEntries = new ArrayList<InputXORDataEntry>();
		this.listInputEnumeratedData = new ArrayList<InputEnumeratedData>();
		this.listTexts = new ArrayList<Text>();
		this.listSubstates = new ArrayList<Substate>();
	}

	// OS MÉTODOS DE REMOÇÃO FORAM RETIRADOS E PRECISAM SER REFEITOS...

	public void insertOutgoingTransition(Transition transition) {
		for (int i = 0; i < this.listOutgoingTransitions.size(); i++) {
			Transition trans = this.listOutgoingTransitions.get(i);
			if (trans.getId().equals(transition.getId()))
				throw new UIDException(UIDException.EXISTING_TRANSITION,
						"There is already a transition with this id");
		}
		listOutgoingTransitions.add(transition);
	}

	public void insertIncomingTransition(Transition transition) {
		for (int i = 0; i < this.listIncomingTransitions.size(); i++) {
			Transition trans = this.listIncomingTransitions.get(i);
			if (trans.getId().equals(transition.getId()))
				throw new UIDException(UIDException.EXISTING_TRANSITION,
						"There is already a transition with this id");
		}
		listIncomingTransitions.add(transition);
	}

	public void insertInputDataItem(InputDataItem dataItem) {
		for (int i = 0; i < this.listDataItems.size(); i++) {
			DataItem item = this.listDataItems.get(i);
			if (item.getName().equals(dataItem.getName()))
				throw new UIDException(UIDException.EXISTING_DATA_ITEM,
						"There is already a data item with this name");
		}
		this.listDataItems.add(dataItem);
	}

	public List<DataItem> getInputDataItem() {
		return null;
	}

	/**
	 * Insere o item de dado na primeira estrutura encontrada. A procura inicia
	 * nas estruturas do estado de interacao. A cada estrutura analisada, a
	 * procura e' feita nas estruturas contidas nela.
	 */
	public void insertInputDataItemInStructure(String nameStructure,
			InputDataItem dataItem) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			struct.insertDataItemInStructureOrSubStructure(nameStructure,
					dataItem);
		}
		// PRECISA ARRUMAR O CÓDIGO PARA GERAR A EXCEÇÃO
	}

	public void insertInputStructure(InputStructure structure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			if (structure instanceof InputStructure
					&& structure.getName().equals(struct.getName()))
				throw new UIDException(UIDException.EXISTING_STRUCTURE,
						"There is already a structure with this name");
		}
		listStructures.add(structure);
	}

	/**
	 * Insere a estrutura na primeira estrutura encontrada. A procura inicia nas
	 * estruturas do estado de interacao. A cada estrutura analisada, a procura
	 * e' feita nas estruturas contidas nela.
	 */
	public void insertInputStructureInStructure(String nameStructure,
			InputStructure structure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			struct.insertStructureInStructureOrSubStructure(nameStructure,
					structure);
		}
		// PRECISA ARRUMAR O CÓDIGO PARA GERAR A EXCEÇÃO
	}

	public void insertInputORDataItem(InputORDataEntry dataItem) {
		for (int i = 0; i < this.listInputORDataEntries.size(); i++) {
			InputORDataEntry data = this.listInputORDataEntries.get(i);
			if (data.getDataItem1().getName()
					.equals(dataItem.getDataItem1().getName())
					&& data.getDataItem2().getName()
							.equals(dataItem.getDataItem2().getName()))
				throw new UIDException(UIDException.EXISTING_DATA_ITEM,
						"There is already an input OR data item with this name");
		}
		this.listInputORDataEntries.add(dataItem);
	}

	public void insertInputXORDataItem(InputXORDataEntry dataItem) {
		for (int i = 0; i < this.listInputXORDataEntries.size(); i++) {
			InputXORDataEntry data = this.listInputXORDataEntries.get(i);
			if (data.getDataItem1().getName()
					.equals(dataItem.getDataItem1().getName())
					&& data.getDataItem2().getName()
							.equals(dataItem.getDataItem2().getName()))
				throw new UIDException(UIDException.EXISTING_DATA_ITEM,
						"There is already an input XOR data item with this name");
		}
		this.listInputXORDataEntries.add(dataItem);
	}

	public void insertInputEnumeratedData(InputEnumeratedData dataItem) {
		for (int i = 0; i < this.listInputEnumeratedData.size(); i++) {
			InputEnumeratedData data = this.listInputEnumeratedData.get(i);
			if (data.getName().equals(dataItem.getName()))
				throw new UIDException(UIDException.EXISTING_DATA_ITEM,
						"There is already a enumerated data item with this name");
		}
		this.listInputEnumeratedData.add(dataItem);
	}

	public void insertOptionInInputEnumeratedData(String nameEnumeratedData,
			String option) {
		for (int i = 0; i < this.listInputEnumeratedData.size(); i++) {
			InputEnumeratedData data = this.listInputEnumeratedData.get(i);
			if (data.getName().equals(nameEnumeratedData)) {
				data.insertOption(option);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_DATA_ITEM,
				"There is no enumerated data with this name");
	}

	public void insertSelectionInInputEnumeratedData(String nameEnumeratedData,
			int min, int max) {
		for (int i = 0; i < this.listInputEnumeratedData.size(); i++) {
			InputEnumeratedData data = this.listInputEnumeratedData.get(i);
			if (data.getName().equals(nameEnumeratedData)) {
				data.insertSelection(min, max);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_DATA_ITEM,
				"There is no enumerated data with this name");
	}

	public void insertOutputDataItem(OutputDataItem dataItem) {
		for (int i = 0; i < this.listDataItems.size(); i++) {
			DataItem elem = this.listDataItems.get(i);
			if (elem.getName().equals(dataItem.getName()))
				throw new UIDException(UIDException.EXISTING_DATA_ITEM,
						"There is already a data item with this name");
		}
		this.listDataItems.add(dataItem);
	}

	public void insertOutputDataItemInStructure(String nameStructure,
			OutputDataItem dataItem) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			struct.insertDataItemInStructureOrSubStructure(nameStructure,
					dataItem);
		}
		// PRECISA ARRUMAR O CÓDIGO PARA GERAR A EXCEÇÃO
	}

	public void insertOutputStructure(OutputStructure structure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			if (structure instanceof OutputStructure
					&& structure.getName().equals(struct.getName()))
				throw new UIDException(UIDException.EXISTING_STRUCTURE,
						"There is already a structure with this name");
		}
		listStructures.add(structure);
	}

	/**
	 * Insere a estrutura retornada pelo sistema na primeira estrutura
	 * encontrada. A procura inicia nas estruturas do estado de interacao. A
	 * cada estrutura analisada, a procura e' feita nas estruturas contidas
	 * nela.
	 */
	public void insertOutputStructureInStructure(String nameStructure,
			OutputStructure structure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			struct.insertStructureInStructureOrSubStructure(nameStructure,
					structure);
		}
		// PRECISA ARRUMAR O CÓDIGO PARA GERAR A EXCEÇÃO
	}

	public void insertText(String idText, String text) {
		for (int i = 0; i < this.listTexts.size(); i++) {
			Text t = this.listTexts.get(i);
			if (t.getId().equals(idText))
				throw new UIDException(UIDException.EXISTING_TEXT,
						"There is a text with this id");
		}
		Text t = new Text(idText);
		t.setText(text);
		this.listTexts.add(t);
	}

	public void defineTextAsOptional(String idText) {
		for (int i = 0; i < this.listTexts.size(); i++) {
			Text t = this.listTexts.get(i);
			if (t.getId().equals(idText)) {
				t.defineAsOptional();
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_TEXT,
				"There is no text with this id");
	}

	public DataItem getDataItem(String nameDataItem) {
		for (int i = 0; i < this.listDataItems.size(); i++) {
			DataItem item = this.listDataItems.get(i);
			if (item.getName().equals(nameDataItem)) {
				return item;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_DATA_ITEM,
				"There is no data item with this name");
	}

	public DataItem getDataItemInStructure(String nameDataItem,
			String nameStructure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			if (struct.getName().equals(nameStructure)) {
				List<DataItem> dataItems = struct.getDataItems();
				for (int j = 0; i < dataItems.size(); j++) {
					DataItem item = dataItems.get(j);
					if (item.getName().equals(nameDataItem)) {
						return item;
					}
				}
			}
		}
		throw new UIDException(
				UIDException.NOT_EXISTING_STRUCTURE_OR_EXISTING_DATA_ITEM,
				"There is no structure with this name or there is no data item with this name");
	}

	public Structure getStructure(String nameStructure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			if (struct.getName().equals(nameStructure)) {
				return struct;
			}
		}
		throw new UIDException(
				UIDException.NOT_EXISTING_STRUCTURE_OR_EXISTING_DATA_ITEM,
				"There is no structure with this name or there is no data item with this name");
	}

	public Structure getStructureInStructure(String nameStructure,
			String nameExternalStructure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure extStruct = this.listStructures.get(i);
			if (extStruct.getName().equals(nameExternalStructure)) {
				List<Structure> structures = extStruct.getStructures();
				for (int j = 0; i < structures.size(); j++) {
					Structure struct = structures.get(j);
					if (struct.getName().equals(nameStructure)) {
						return struct;
					}
				}
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STRUCTURE,
				"There is no structure with this name");
	}

	public Vector<Structure> getAllStructures() {
		Vector<Structure> structures = new Vector<Structure>();
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			structures.add(struct);
		}
		// adicionado por Filipe, para dar suporte inicial aos SubStates.
		for (Substate s : listSubstates) {
			structures.addAll(s.getAllStructures());
		}
		return structures;
	}

	public Vector<Structure> getAllStructuresAndInternalStructures() {
		Vector<Structure> structures = new Vector<Structure>();
		for (int i = 0; i < this.listStructures.size(); i++) {
			Structure struct = this.listStructures.get(i);
			structures.add(struct);
			structures.addAll(struct.getAllStructuresAndInternalStructures());
		}

		// adicionado por Filipe, para dar suporte inicial aos SubStates.
		for (Substate s : listSubstates) {
			Vector<Structure> strs = s.getAllStructures();

			for (int i = 0; i < strs.size(); i++) {
				Structure struct = strs.get(i);
				structures.add(struct);
				structures.addAll(struct
						.getAllStructuresAndInternalStructures());
			}

		}
		return structures;
	}

	public Vector<DataItem> getAllDataItemsWithNoStructures() {
		Vector<DataItem> dataItems = new Vector<DataItem>();
		for (int i = 0; i < this.listDataItems.size(); i++) {
			DataItem item = this.listDataItems.get(i);
			dataItems.add(item);
		}
		// adicionado por Filipe, para dar suporte inicial aos SubStates.
		for (Substate s : listSubstates) {
			dataItems.addAll(s.getAllDataItemsWithNoStructures());
		}
		return dataItems;

	}

	public String getId() {
		return id;
	}

	// ///////////////////////////////////////////////////////////////////////

	public void insertInputOptionalDataItem(InputOptionalDataItem dataItem) {
		for (int i = 0; i < this.listDataItems.size(); i++) {
			UIDElement elem = this.listDataItems.get(i);
			if (elem instanceof InputOptionalDataItem
					&& ((InputOptionalDataItem) elem).getName().equals(
							dataItem.getName()))
				throw new UIDException(UIDException.EXISTING_DATA_ITEM,
						"There is already a data item with this name");
		}
		listDataItems.add(dataItem);

	}

	public void insertInputOptionalDataItemInStructure(String nameStructure,
			InputOptionalDataItem dataItem) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			UIDElement elem = this.listStructures.get(i);
			if (elem instanceof InputStructure) {
				boolean insertionOk = ((InputStructure) elem)
						.insertInputOptionalDataItemInStructure(nameStructure,
								dataItem);
				if (insertionOk)
					return;
			}
		}
		throw new UIDException(
				UIDException.NOT_EXISTING_STRUCTURE_OR_EXISTING_DATA_ITEM,
				"There is no structure with this name or there is already a data item with this name");

	}

	public OutputDataItem getOutputDataItem(String nameDataItem) {
		for (int i = 0; i < this.listDataItems.size(); i++) {
			UIDElement elem = this.listDataItems.get(i);
			if (elem instanceof OutputDataItem
					&& ((OutputDataItem) elem).getName().equals(nameDataItem)) {
				return (OutputDataItem) elem;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_DATA_ITEM,
				"There is no data item with this name");
	}

	public OutputDataItem getOutputDataItemInStructure(String nameDataItem,
			String nameStructure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			UIDElement elem = this.listStructures.get(i);
			if (elem instanceof OutputStructure) {
				OutputDataItem dataItem = ((OutputStructure) elem)
						.getOutputDataItemFromStructure(nameDataItem,
								nameStructure);
				if (dataItem != null)
					return dataItem;
			}
		}
		throw new UIDException(
				UIDException.NOT_EXISTING_STRUCTURE_OR_EXISTING_DATA_ITEM,
				"There is no structure with this name or there is no data item with this name");
	}

	public OutputStructure getOutputStructure(String nameStructure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			UIDElement elem = this.listStructures.get(i);
			if (elem instanceof OutputStructure
					&& ((OutputStructure) elem).getName().equals(nameStructure)) {
				return (OutputStructure) elem;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STRUCTURE,
				"There is no structure with this name");
	}

	public OutputStructure getOutputStructureInStructure(String nameStructure,
			String nameExternalStructure) {
		for (int i = 0; i < this.listStructures.size(); i++) {
			UIDElement elem = this.listStructures.get(i);
			if (elem instanceof OutputStructure) {
				OutputStructure structure = ((OutputStructure) elem)
						.getOutputStructureFromStructure(nameStructure,
								nameExternalStructure);
				if (structure != null)
					return structure;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STRUCTURE,
				"There is no structure with this name");
	}

	// SUBSTATE
	public void insertSubstate(String idSubstate) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate))
				throw new UIDException(UIDException.EXISTING_STATE,
						"There is a substate with this id");
		}
		Substate s = new Substate(idSubstate);
		listSubstates.add(s);

	}

	public void insertTextInSubstate(String idSubstate, String idText,
			String text) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertText(idText, text);
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name or there is already a text with this name");

	}

	public void defineTextInSubstateAsOptional(String idSubstate, String idText) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).defineTextAsOptional(idText);
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputOptionalDataItemInSubstate(String idSubstate,
			InputOptionalDataItem dataItem) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputOptionalDataItem(dataItem);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");
	}

	public void insertInputDataItemInSubstate(String idSubstate,
			InputDataItem dataItem) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputDataItem(dataItem);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputORDataItemInSubstate(String idSubstate,
			InputORDataEntry oRdataEntry) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputORDataItem(oRdataEntry);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputXORDataItemInSubstate(String idSubstate,
			InputXORDataEntry XORdataEntry) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputXORDataItem(XORdataEntry);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputEnumeratedDataInSubstate(String idSubstate,
			InputEnumeratedData enumeratedData) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputEnumeratedData(enumeratedData);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertSelectionInInputEnumeratedDataInSubstate(
			String idSubstate, String nameEnumeratedData, int min, int max) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertSelectionInInputEnumeratedData(
						nameEnumeratedData, min, max);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertOptionInInputEnumeratedDataInSubstate(String idSubstate,
			String nameEnumeratedData, String option) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertOptionInInputEnumeratedData(
						nameEnumeratedData, option);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputStructureInSubstate(String idSubstate,
			InputStructure structure) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputStructure(structure);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputDataItemInStructureInSubstate(String idSubstate,
			String nameStructure, InputDataItem dataItem) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputDataItemInStructure(nameStructure,
						dataItem);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertInputStructureInStructureInSubstate(String idSubstate,
			String nameStructure, InputStructure structure) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertInputStructureInStructure(
						nameStructure, structure);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public Substate getSubState(String idSubstate) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				return (Substate) elem;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertOutputDataItemInSubstate(String idSubstate,
			OutputDataItem dataItem) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertOutputDataItem(dataItem);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertOutputStructureInSubstate(String idSubstate,
			OutputStructure structure) {

		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertOutputStructure(structure);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertOutputDataItemInStructureInSubstate(String idSubstate,
			String nameStructure, OutputDataItem dataItem) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertOutputDataItemInStructure(
						nameStructure, dataItem);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	public void insertOutputStructureInStructureInSubstate(String idSubstate,
			String nameStructure, OutputStructure structure) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem instanceof Substate
					&& ((Substate) elem).getId().equals(idSubstate)) {
				((Substate) elem).insertOutputStructureInStructure(
						nameStructure, structure);
				return;
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");

	}

	// ///////////////////////////////////////////////////////////////////

	public OutputDataItem getOutputDataItemInSubstate(String nameDataItem,
			String idSubstate) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem.getId().equals(idSubstate)) {
				return elem.getOutputDataItem(nameDataItem);
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");
	}

	public OutputStructure getOutputStructureInSubstate(String nameStructure,
			String idSubstate) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem.getId().equals(idSubstate)) {
				return elem.getOutputStructure(nameStructure);
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");
	}

	public OutputDataItem getOutputDataItemInStructureInSubstate(
			String nameDataItem, String idSubstate, String nameStructure) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem.getId().equals(idSubstate)) {
				return elem.getOutputDataItemInStructure(nameDataItem,
						nameStructure);
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");
	}

	public OutputStructure getOutputStructureInStructureInSubstate(
			String nameNewStructure, String idSubstate, String nameStructure) {
		for (int i = 0; i < this.listSubstates.size(); i++) {
			Substate elem = this.listSubstates.get(i);
			if (elem.getId().equals(idSubstate)) {
				return elem.getOutputStructureInStructure(nameNewStructure,
						nameStructure);
			}
		}
		throw new UIDException(UIDException.NOT_EXISTING_STATE,
				"There is no substate with this name");
	}

	public List<Transition> getAllOutgoingTransitions() {
		// TODO Auto-generated method stub
		return listOutgoingTransitions;
	}

	public List<Substate> getAllSubStates() {
		// TODO Auto-generated method stub
		return listSubstates;
	}

	public List<DataItem> getAllDataItens() {
		// TODO Auto-generated method stub
		return listDataItems;
	}

	public List<InputEnumeratedData> getAllInputEnumeratedData() {
		// TODO Auto-generated method stub
		return listInputEnumeratedData;
	}

	public List<InputORDataEntry> getAllInputORDataEntries() {
		// TODO Auto-generated method stub
		return listInputORDataEntries;
	}

	public List<InputXORDataEntry> getAllInputXORDataEntries() {
		// TODO Auto-generated method stub
		return listInputXORDataEntries;
	}

	public List<Text> getAllTexts() {
		// TODO Auto-generated method stub
		return listTexts;
	}
}